package com.jt.common.util;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

import org.apache.commons.lang3.ArrayUtils;


public final class ReflectUtils {
  
  /**
   * cacheFields:类反射域缓存
   */
  private static Map<String, Field[]> fieldCache = new HashMap<>();
  
  /**
   * 禁用实例化
   */
  private ReflectUtils(){}
  
  /** 
   *  @Description  : 获取对象全部域(属性)
   *  @return         : Field[]
   *  @Creation Date  : 2016年5月19日 下午5:19:31 
   *  @Author         : chichangchao
   */
  public static Field[] getFields(Object obj) {
    // 获取类模板
    Class<?> clazz = obj.getClass();
    // 获取全部域(本类+父类)
    // 先从缓存里获取，若不存在，则直接通过反射获取，然后存入缓存
    String clazzName = clazz.getSimpleName();
    Field[] fields = fieldCache.get(clazzName);
    if(ArrayUtils.isEmpty(fields))
      fields = getAllFields(clazz);
    return fields;
  }
  
  
  /** 
   *  @Description	: 获取某个对象中的某个域(属性)
   *  @return         : Field
   *  @Creation Date  : 2016年5月22日 下午11:29:24 
   *  @Author         : chichangchao
   */
  public static Field getField(Object obj, String name){
    Field[] fields = ReflectUtils.getFields(obj);
    if(ArrayUtils.isEmpty(fields)) return null;
    for (Field field : fields) {
      if(Objects.equals(field.getName(), name)){
        field.setAccessible(true);
        return field;
      }
    }
    return null;
  }
  
  
  /** 
   *  @Description	: 递归获取目标类模板clazz的全部域(不包含Object)
   *  @return         : Field[]
   *  @Creation Date  : 2016年5月19日 下午5:22:23 
   *  @Author         : chichangchao
   */
  private static Field[] getAllFields(Class<?> clazz){
    if(clazz.getSuperclass() != null && !Object.class.getSimpleName().equals(clazz.getSuperclass().getSimpleName())){
      return ArrayUtils.addAll(clazz.getDeclaredFields(), getAllFields(clazz.getSuperclass()));
    }
    return clazz.getDeclaredFields();
  }
}
